#include <Kharlia/Engine/Common.h>
#include <Kharlia/Engine/Init.h>
#include <Kharlia/Engine/World.h>

namespace kharlia { namespace engine {

void _InitWorldBindings() {
    enum_<ENetMode>("ENetMode")
        .value("NM_STANDALONE", NM_STANDALONE)
        .value("NM_DEDICATED_SERVER", NM_DEDICATED_SERVER)
        .value("NM_LISTEN_SERVER", NM_LISTEN_SERVER)
        .value("NM_CLIENT", NM_CLIENT)
        .export_values()
        ;

    class_<CGame, bases<core::CObject>, noncopyable>
        ("CGameBase", init<TPtr<CWorld>>())
        .add_property("World", &CGame::GetWorld)
        //.def_readwrite("_World", &CGame::mWorld) // for unpickling
        .def_readonly("Paused", &CGame::mPaused)
        //.def_readonly("Inited", &CGame::mInited)
        .def_readonly("RealTime", &CGame::mRealTime)
        .def_readonly("GameTime", &CGame::mGameTime)
        .def("Init", &CGame::InitImpl)
        .def("Exit", &CGame::ExitImpl)
        .def_pickle(CGame::Pickler())
        ;

    KH_IMPL_GC(CGame);
    RegisterPtrConverter<CGame>();

    class_
        <CWorld, bases<core::CObject>, boost::noncopyable>
        ("CWorldBase", init<>())
        .def_readonly("Ticking", &CWorld::mTicking)
        .def("Clear", &CWorld::ClearImpl)
        .def("AddLevel", &CWorld::AddLevelImpl)
        .def("RemoveLevel", &CWorld::RemoveLevelImpl)
        .def("ClearLevels", &CWorld::ClearLevels, (arg("clear")=false))
        .def("GetLevel", &CWorld::GetLevel)
        .def("SetLevelClass", &CWorld::SetLevelClass).staticmethod("SetLevelClass")
        .add_property("Engine", &CWorld::GetEngine)
        .add_property("IsUnbound", &CWorld::GetIsUnbound, &CWorld::SetIsUnbound)
        .def_readonly("Levels", &CWorld::mLevels)
        .def_readonly("LevelHashMap", &CWorld::mLevelHashMap)
        .def_readonly("DefaultLevel", &CWorld::mDefaultLevel)
        .def_readwrite("_DefaultLevel", &CWorld::mDefaultLevel)
        .def("AddPlayer", &CWorld::AddPlayer, (arg("player"), arg("remoteRole")=ENetRole::NONE))
        .def("RemovePlayer", &CWorld::RemovePlayer)
        .def("IterPlayers", &CWorld::IterPlayers)
        .def("StartGame", &CWorld::StartGame)
        .def("StopGame", &CWorld::StopGame)
        .def_readonly("Game", &CWorld::mGame)
        .def_readwrite("GameClass", &CWorld::mGameClass)
        .add_property("GameStarted", &CWorld::GetGameStarted)
        // Net
        .def("NetListen", &CWorld::NetListen)
        //.def("NetConnect", &CWorld::NetConnect)
        .def("NetShutdown", &CWorld::NetShutdown)
        //.def("NetSendDebugMessage", &CWorld::NetSendDebugMessage)
        //.def("NetSendActorRPC", &CWorld::NetSendActorRPC)
        //.add_property("NetIsEnabled", &CWorld::GetNetIsEnabled)
        //.add_property("NetIsServer", &CWorld::GetNetIsServer)
        //.add_property("NetIsClient", &CWorld::GetNetIsClient)
        //.add_property("NetTickRate", &CWorld::GetNetTickRate, &CWorld::SetNetTickRate)
        //.add_property("NetRepRate", &CWorld::GetNetRepRate, &CWorld::SetNetRepRate)
        .add_property("NetMode", &CWorld::GetNetMode)
        .def_pickle(CWorld::Pickler())
        ;

    KH_IMPL_GC(CWorld);
    RegisterPtrConverter<CWorld>();
}

}}